/**
 * 前端密码加密工具
 * 使用RSA公钥加密密码，确保传输安全
 */

import { ElMessage } from 'element-plus';

// 加密相关的接口定义
interface PublicKeyResponse {
    success: boolean;
    data: {
        publicKey: string;
        algorithm: string;
        keySize: number;
        hash: string;
    };
    message: string;
}

interface PasswordStrengthResult {
    score: number;
    strength: 'weak' | 'medium' | 'strong';
    checks: {
        length: boolean;
        uppercase: boolean;
        lowercase: boolean;
        number: boolean;
        special: boolean;
    };
    suggestions: string[];
}

class PasswordEncryption {
    private publicKey: string | null = null;
    private crypto: SubtleCrypto | null = null;

    constructor() {
        // 检查浏览器支持
        if (typeof window !== 'undefined' && window.crypto && window.crypto.subtle) {
            this.crypto = window.crypto.subtle;
        }
    }

    /**
     * 初始化加密工具，获取公钥
     */
    async initialize(): Promise<boolean> {
        try {
            if (!this.crypto) {
                throw new Error('当前浏览器不支持Web Crypto API');
            }

            // 从后端获取RSA公钥
            const response = await fetch('/api/security/public-key');
            if (!response.ok) {
                throw new Error(`获取公钥失败: ${response.statusText}`);
            }

            const result: PublicKeyResponse = await response.json();
            if (!result.success) {
                throw new Error(`获取公钥失败: ${result.message}`);
            }

            this.publicKey = result.data.publicKey;
            console.log('✅ RSA公钥获取成功');
            return true;

        } catch (error) {
            console.error('❌ 密码加密工具初始化失败:', error);
            ElMessage.error(`加密工具初始化失败: ${error instanceof Error ? error.message : '未知错误'}`);
            return false;
        }
    }

    /**
     * 将PEM格式的公钥转换为CryptoKey
     */
    private async importPublicKey(): Promise<CryptoKey> {
        if (!this.publicKey || !this.crypto) {
            throw new Error('公钥未获取或浏览器不支持加密功能');
        }

        // 清理PEM格式，提取Base64数据
        const pemHeader = '-----BEGIN PUBLIC KEY-----';
        const pemFooter = '-----END PUBLIC KEY-----';
        const pemContents = this.publicKey
            .replace(pemHeader, '')
            .replace(pemFooter, '')
            .replace(/\s/g, '');

        // Base64解码
        const binaryDer = window.atob(pemContents);
        const der = new Uint8Array(binaryDer.length);
        for (let i = 0; i < binaryDer.length; i++) {
            der[i] = binaryDer.charCodeAt(i);
        }

        // 导入公钥
        return await this.crypto.importKey(
            'spki',
            der.buffer,
            {
                name: 'RSA-OAEP',
                hash: 'SHA-256'
            },
            false,
            ['encrypt']
        );
    }

    /**
     * 加密密码
     */
    async encryptPassword(plainPassword: string): Promise<string> {
        try {
            if (!plainPassword) {
                throw new Error('密码不能为空');
            }

            if (!this.publicKey) {
                const initialized = await this.initialize();
                if (!initialized) {
                    throw new Error('加密工具初始化失败');
                }
            }

            const publicKey = await this.importPublicKey();
            const encoder = new TextEncoder();
            const data = encoder.encode(plainPassword);

            // RSA-OAEP加密
            const encrypted = await this.crypto!.encrypt(
                {
                    name: 'RSA-OAEP'
                },
                publicKey,
                data
            );

            // 转换为Base64字符串
            const encryptedArray = new Uint8Array(encrypted);
            return window.btoa(String.fromCharCode(...encryptedArray));

        } catch (error) {
            console.error('❌ 密码加密失败:', error);
            throw new Error(`密码加密失败: ${error instanceof Error ? error.message : '未知错误'}`);
        }
    }

    /**
     * 检查密码强度
     */
    async checkPasswordStrength(password: string): Promise<PasswordStrengthResult | null> {
        try {
            const response = await fetch('/api/security/password-strength', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ password })
            });

            if (!response.ok) {
                throw new Error(`密码强度检查失败: ${response.statusText}`);
            }

            const result = await response.json();
            return result.success ? result.data : null;

        } catch (error) {
            console.error('❌ 密码强度检查失败:', error);
            return null;
        }
    }

    /**
     * 生成强密码建议
     */
    async generateStrongPassword(length: number = 12): Promise<string | null> {
        try {
            const response = await fetch(`/api/security/generate-password?length=${length}`);
            if (!response.ok) {
                throw new Error(`生成强密码失败: ${response.statusText}`);
            }

            const result = await response.json();
            return result.success ? result.data.password : null;

        } catch (error) {
            console.error('❌ 生成强密码失败:', error);
            return null;
        }
    }

    /**
     * 测试加密功能
     */
    async testEncryption(testPassword: string = 'test123456'): Promise<boolean> {
        try {
            const encryptedPassword = await this.encryptPassword(testPassword);
            console.log('🔒 测试密码加密成功，加密结果长度:', encryptedPassword.length);

            // 调用后端测试接口
            const response = await fetch('/api/security/test-encryption', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ encryptedPassword })
            });

            if (!response.ok) {
                throw new Error(`测试失败: ${response.statusText}`);
            }

            const result = await response.json();
            if (result.success && result.data.verificationResult) {
                console.log('✅ 端到端加密测试成功');
                return true;
            } else {
                throw new Error('后端验证失败');
            }

        } catch (error) {
            console.error('❌ 加密测试失败:', error);
            return false;
        }
    }

    /**
     * 检查浏览器兼容性
     */
    isSupported(): boolean {
        return !!(typeof window !== 'undefined' && window.crypto && window.crypto.subtle);
    }

    /**
     * 获取浏览器兼容性信息
     */
    getCompatibilityInfo(): { supported: boolean; features: Record<string, boolean> } {
        const features = {
            crypto: typeof window !== 'undefined' && !!window.crypto,
            subtle: typeof window !== 'undefined' && !!window.crypto?.subtle,
            textEncoder: typeof TextEncoder !== 'undefined',
            textDecoder: typeof TextDecoder !== 'undefined',
            atob: typeof window !== 'undefined' && !!window.atob,
            btoa: typeof window !== 'undefined' && !!window.btoa,
        };

        const supported = Object.values(features).every(Boolean);

        return { supported, features };
    }
}

// 创建单例实例
const passwordEncryption = new PasswordEncryption();

// 密码强度指示器组件数据
export const getPasswordStrengthColor = (strength: string): string => {
    switch (strength) {
        case 'weak': return '#f56c6c';
        case 'medium': return '#e6a23c';
        case 'strong': return '#67c23a';
        default: return '#909399';
    }
};

export const getPasswordStrengthText = (strength: string): string => {
    switch (strength) {
        case 'weak': return '弱';
        case 'medium': return '中';
        case 'strong': return '强';
        default: return '未知';
    }
};

export default passwordEncryption;
export { PasswordEncryption, type PasswordStrengthResult, type PublicKeyResponse };